/**
 * @ignore 
 * @define gui相关
 */
namespace ui {

	/**
	 * 将显示对象居中放置
	 * @param obj 目标对象
	 * @param container 需要加入的容器 *默认无
	 * @param consider 考虑目标对象已进行的锚点和缩放变化 *默认否
	 * @description 当consider=ture时对象在显示效果上居中
	 * @return 目标对象自身
	 */
	export function resetCenter<T extends egret.DisplayObject>(obj: T, container?: egret.DisplayObjectContainer, consider: boolean = false): T {
		if (!obj) return;
		if (container) container.addChild(obj);
		if (!obj.parent) return;
		if (consider) {
			obj.x = (obj.parent.width - obj.width * obj.scaleX) / 2 + obj.anchorOffsetX * obj.scaleX;
			obj.y = (obj.parent.height - obj.height * obj.scaleY) / 2 + obj.anchorOffsetY * obj.scaleY;
		} else {
			obj.x = (obj.parent.width - obj.width) / 2;
			obj.y = (obj.parent.height - obj.height) / 2;
		}
		return obj;
	}

	/**
	 * 将显示对象锚点设置到当前几何中心
	 * @param obj 目标对象
	 * @param stay 是否保持原位置 *默认是
	 * @return 目标对象自身
	 */
	export function resetAnchorCenter<T extends egret.DisplayObject>(obj: T, stay: boolean = true): T {
		let [oriX, oriY] = [obj.anchorOffsetX, obj.anchorOffsetY];
		obj.anchorOffsetX = obj.width / 2;
		obj.anchorOffsetY = obj.height / 2;
		if (stay) {
			obj.x += (obj.anchorOffsetX - oriX);
			obj.y += (obj.anchorOffsetY - oriY);
		}
		return obj;
	}

	/**
	 * 将帧动画锚点设置到原剪辑中心
	 * @description 该方法适用于帧动画每张图片大小一致
	 * @param mc 帧动画
	 * @return 帧动画自身
	 */
	export function resetMcCenter(mc: egret.MovieClip): egret.MovieClip {
		mc.anchorOffsetX = mc.width / 2 + mc['offsetPoint'].x;
		mc.anchorOffsetY = mc.height / 2 + mc['offsetPoint'].y;
		return mc;
	}

	export function setTop<T extends egret.DisplayObject>(obj: T, container?: egret.DisplayObjectContainer, options?: hjc.DisplayOptions): T {
		return setLayer(obj, 1, container, options);
	}

	export function setBottom<T extends egret.DisplayObject>(obj: T, container?: egret.DisplayObjectContainer, options?: hjc.DisplayOptions): T {
		return setLayer(obj, -1, container, options);
	}

	// n<0 倒数第n层 n>0 正数第n层
	export function setLayer<T extends egret.DisplayObject>(obj: T, layer: number, container?: egret.DisplayObjectContainer, options?: hjc.DisplayOptions): T {
		if (!obj) { hjc.warn('set layer of empty object!'); return null; }
		if (!obj.parent && !container) { hjc.warn('parent required!'); return null; }
		if (notEmpty(options)) ui.setDisplay(obj, options);
		if (container) container.addChild(obj);
		if (layer > 0) obj.parent.setChildIndex(obj, obj.parent.numChildren - layer);
		else if (layer < 0) obj.parent.setChildIndex(obj, - layer - 1);
		else hjc.warn('"layer"(int,≠0) required!');
		return obj;
	}

	export function setDisplay<T extends egret.DisplayObject>(obj: T, options: hjc.DisplayOptions, container?: egret.DisplayObjectContainer): T {
		if (!obj) { hjc.warn('set display to empty object!'); return null; }
		if (!!container) container.addChild(obj);
		if (notEmpty(options)) {
			if (!!options.name) obj.name = options.name;
			if (numeric(options.x)) obj.x = options.x;
			if (numeric(options.y)) obj.y = options.y;
			if (numeric(options.size)) { obj.width = options.size; obj.height = options.size; }
			if (numeric(options.width)) obj.width = options.width;
			if (numeric(options.height)) obj.height = options.height;
			if (numeric(options.scale)) { obj.scaleX = options.scale; obj.scaleY = options.scale; }
			if (numeric(options.scaleX)) obj.scaleX = options.scaleX;
			if (numeric(options.scaleY)) obj.scaleY = options.scaleY;
			if (numeric(options.rotation)) obj.rotation = options.rotation;
			if (numeric(options.skewX)) obj.skewX = options.skewX;
			if (numeric(options.skewY)) obj.skewX = options.skewX;
			if (numeric(options.offset)) { obj.anchorOffsetX = options.offset; obj.anchorOffsetY = options.offset; }
			if (numeric(options.offsetX)) obj.anchorOffsetX = options.offsetX;
			if (numeric(options.offsetY)) obj.anchorOffsetY = options.offsetY;
			if (numeric(options.alpha)) obj.alpha = options.alpha;
			if (isBoolean(options.visible)) obj.visible = options.visible;
			if (isBoolean(options.touchEnabled)) obj.touchEnabled = options.touchEnabled;
			if (isBoolean(options.touchChildren) && obj instanceof egret.DisplayObjectContainer) obj.touchChildren = options.touchChildren;
			if (options.centered) resetAnchorCenter(obj, true);
		}
		return obj;
	}

	/**
 	 * 设置显示对象缩放值
 	 * @param obj 显示对象
	 * @param scale （横）缩放比 *默认1
	 * @param scaleY 纵缩放比
	 * @return 显示对象自身
 	 */
	export function setScale<T extends egret.DisplayObject>(obj: T, scale: number = 1, scaleY?: number): T {
		if (!obj) return null;
		obj.scaleX = scale;
		obj.scaleY = scaleY ? scaleY : scale;
		return obj;
	}

	/**
 	 * 从显示队列移除显示对象
 	 * @param obj 显示对象
 	 */
	export function remove(obj: egret.DisplayObject): void {
		if (!obj || !obj.parent) return;
		obj.parent.removeChild(obj);
	}

	/**
	 * 获得容器所有直接子对象
	 * @param container {egret.DisplayObjectContainer} 显示容器
	 * @return 显示对象数组
	*/
	export function getChildren<T extends egret.DisplayObject>(container: egret.DisplayObjectContainer, type?: any): T[] {
		if (!container) return [];
		let [children, num] = [[], container.numChildren];
		for (let i = 0; i < num; i++) {
			let disObj = container.getChildAt(i)
			if (!!type) {
				if (disObj instanceof type) children.push(disObj);
			} else children.push(disObj);
		}
		return children;
	}

	/**
	 * 完全填充父控件
	 * @param obj 目标对象
	 * @param container 需要加入的容器 
	 * @return 目标对象自身
	 */
	export function fillParent<T extends egret.DisplayObject>(obj: T, container?: egret.DisplayObjectContainer): T {
		if (!obj) return;
		if (container) container.addChild(obj);
		if (!obj.parent) return;
		obj.x = 0; obj.y = 0;
		obj.width = obj.parent.width;
		obj.height = obj.parent.height;
		return obj;
	}


	export function getGrandchildByName<T extends egret.DisplayObject>(container: egret.DisplayObjectContainer, name: string): T {
		for (let child of ui.getChildren<T>(container)) {
			if (child.name === name) return child;
			else if (child instanceof egret.DisplayObjectContainer) {
				let found = ui.getGrandchildByName<T>(child, name);
				if (found) return found;
			}
		}
		return null;
	}

	export function setDragger<T extends egret.DisplayObject>(obj: T, options?: hjc.DragOptions): T {
		if (!obj) { hjc.wrong('ui.setDragger', 'object', 'is empty'); return obj; }
		return hjc.DraggerManager.instance<hjc.DraggerManager>().attach(obj, options);
	}

	export function removeDragger<T extends egret.DisplayObject>(obj: T): T {
		if (!obj) { hjc.wrong('ui.removeDragger', 'object', 'is empty'); return obj; }
		return hjc.DraggerManager.instance<hjc.DraggerManager>().dettach(obj);
	}

	Object.defineProperty(egret.DisplayObject.prototype, 'draggable', {
		get: function () { return this.$draggable },
		set: function (draggable) {
			this.$draggable = draggable;
			if (draggable) hjc.DraggerManager.instance<hjc.DraggerManager>().attach(this);
			else hjc.DraggerManager.instance<hjc.DraggerManager>().dettach(this);
		},
		enumerable: true,
		configurable: true,
	});
}